package login

import (
	"log"
	"net/http"

	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"

	"toy-car/models"
	"toy-car/pkg/e"
	"toy-car/pkg/setting"
	"toy-car/pkg/util"
	"toy-car/services"

	"github.com/go-redis/redis"
	"github.com/mojocn/base64Captcha"
	// "github.com/unknwon/com"
)

var store = base64Captcha.DefaultMemStore

type auth struct {
	Username  string `json:"username" valid:"Required; MaxSize(50)"`
	Password  string `json:"password" valid:"Required; MaxSize(50)"`
	Captcha   string `json:"captcha"`   // 验证码
	CaptchaId string `json:"captchaId"` // 验证码ID
}

func DoLogin(c *gin.Context) {
	// post参数获取
	loginData := auth{}
	c.BindJSON(&loginData)

	// 参数合法性验证
	valid := validation.Validation{}
	ok, _ := valid.Valid(&loginData)

	data := make(map[string]interface{})

	if !ok {
		e.Fail(e.INVALID_PARAMS, nil, "", c)
		return
	}

	if setting.UseCaptcha {
		if ok := store.Verify(loginData.CaptchaId, loginData.Captcha, true); !ok {
			e.Fail(e.INVALID_PARAMS, nil, "", c)
			return
		}
	}

	systemUser, er := models.GetSysUserByLoginName(loginData.Username)
	if er != nil {
		e.Fail(e.ERROR_USERNAME_OR_PASSWORD, nil, "", c)
		return
	}

	// 比对查询数据中password与用户提交的password
	md5Pass := util.MD5V([]byte(loginData.Password))
	if md5Pass != systemUser.Password {
		e.Fail(e.ERROR_USERNAME_OR_PASSWORD, nil, "", c)
		return
	}

	// 查看用户状态
	if systemUser.UserStatus == models.SYSUSER_STATUS_LOCKED {
		e.Fail(e.ERROR_USER_LOCKED, nil, "", c)
		return
	}

	// user := models.CheckAndFetchAuth(loginData.Username, loginData.Password)
	// if user.ID == 0 {
	// 	e.Fail(e.ERROR_USERNAME_OR_PASSWORD, nil, "", c)
	// 	return
	// }

	// 登录的后续操作

	// var isAdmin = systemUser.UserType == models.SYSUSER_TYPE_ADMIN

	token, err := util.GenerateToken(systemUser.LoginName, systemUser.ShowName, systemUser.UserID, systemUser.UserType)
	if err != nil {
		e.Fail(e.ERROR_AUTH_CHECK_TOKEN_FAIL, nil, "", c)
		return
	}

	data["token"] = token
	var jwtStr string
	if err, jwtStr = services.GetRedisJWT(systemUser.LoginName); err == redis.Nil {
		if err := services.SetRedisJWT(token, systemUser.LoginName); err != nil {
			log.Println("redis 设置token错误")
			e.Fail(e.ERROR, nil, "", c)
			return
		}
	} else if err != nil {
		log.Printf("%v", err)
		log.Println("redis 读取错误")
		e.Fail(e.ERROR, nil, "", c)
		return
	}

	var blackJWT models.JwtBlacklist
	blackJWT.Jwt = jwtStr
	if err := models.JsonInBlacklist(blackJWT); err != nil {
		log.Println("黑名单报错失败")
		e.Fail(e.ERROR, nil, "", c)
		return
	}

	data["status"] = "ok"
	c.Header("X-NEW-TOKEN", "testtoken")
	e.Success(data, "", c)
}

func Captcha(c *gin.Context) {
	driver := base64Captcha.NewDriverDigit(50, 100, 1, 0.7, 80)
	cp := base64Captcha.NewCaptcha(driver, store)
	id, b64s, err := cp.Generate()
	code := e.SUCCESS
	if err != nil {
		code = e.ERROR
	}
	data := make(map[string]interface{})
	data["captchaId"] = id
	data["picPath"] = b64s
	c.JSON(http.StatusOK, gin.H{
		"code": code,
		"msg":  e.GetMSG(code),
		"data": data,
	})
}

func DoLogout(c *gin.Context) {
	// todo 清除redis中的数据
	// 删除jwt
	// 目前是客户端删除认证信息
}
